home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / mewin10s.zip / MSWFONT.C < prev    next >
C/C++ Source or Header  |  1992-04-12  |  20KB  |  599 lines

  1. /* The routines in this file provide font control functions under
  2.    the Microsoft Windows environment on an IBM-PC or compatible
  3.    computer.
  4.  
  5.    Must be compiled with Borland C++ 2.0.
  6.  
  7.    It should not be compiled if the WINDOW_MSWIN symbol is not set */
  8.  
  9. #include    "estruct.h"
  10. #include    <stdio.h>
  11. #include    "eproto.h"
  12. #include    "edef.h"
  13.  
  14. #include    "mswin.h"
  15.  
  16. extern char *itoa (int value, char *string, int radix);
  17. extern int   atoi (char *s);
  18.  
  19. static TEXTMETRIC   Metrics;
  20. static HFONT        hNewFont;
  21. static char         FaceName[LF_FACESIZE];
  22.  
  23. /* SelectFont:  Selects the emacs-chosen font in the Device Context */
  24. /* ==========                                                       */
  25.  
  26. HFONT far pascal SelectFont (HDC hDC, HFONT hFont)
  27.  
  28. /* just like SelectObject, this function returns the previously selected
  29.    font handle */
  30. {
  31.     HFONT   hPrevFont;
  32.  
  33.     SetMapMode (hDC, MM_TEXT);
  34.     hPrevFont= SelectObject (hDC, hFont ?
  35.                   hFont :
  36.                                   GetStockObject (SYSTEM_FIXED_FONT));
  37.     return hPrevFont;
  38. } /* SelectFont */
  39.  
  40. /* GetFontMetrics:  retrieves the TEXTMETRIC and face name of a given font */
  41. /* ==============                                                          */
  42.  
  43. static void pascal near GetFontMetrics (HFONT hFont, TEXTMETRIC *Metrics,
  44.                                         char *FaceName)
  45. /* If either Metrics of FaceName is NULL, the corresponding value is not
  46.    returned. If not NULL, FaceName must point to a string containing at
  47.    least LF_FACESIZE characters */
  48. {
  49.     HDC     hDC;
  50.     HFONT   hPrevFont;
  51.  
  52.     hDC = GetDC (hFrameWnd);
  53.     hPrevFont = SelectFont (hDC, hFont);
  54.     if (Metrics) GetTextMetrics (hDC, Metrics);
  55.     if (FaceName) GetTextFace (hDC, LF_FACESIZE, FaceName);
  56.     SelectObject (hDC, hPrevFont);
  57.     ReleaseDC (hFrameWnd, hDC);
  58. } /* GetFontMetrics */
  59.  
  60. /* UpdateMaxRowCol: update the maximas displayed on the dialog box */
  61. /* ===============                                                 */
  62.  
  63. static void pascal near UpdateMaxRowCol (HWND hDlg, HFONT hFont)
  64. {
  65.     CellMetrics cm;
  66.     char    text[17];
  67.  
  68.     BuildCellMetrics (&cm, hFont);
  69.     SetDlgItemText (hDlg, ID_MAXROWS,
  70.             itoa (DisplayableRows (hFrameWnd, -1, &cm), text, 10));
  71.     SetDlgItemText (hDlg, ID_MAXCOLUMNS,
  72.             itoa (DisplayableColumns (hFrameWnd, -1, &cm), text, 10));
  73. } /* UpdateMaxRowCol */
  74.  
  75. /* UpdateSample:    Update the sample text displayed on the dialog box */
  76. /* ============                                                        */
  77.  
  78. static void pascal near UpdateSample (HWND hDlg, HFONT hFont,
  79.                                       TEXTMETRIC *m, char *FaceName)
  80. {
  81. #define FONTSAMPLESIZE  LF_FACESIZE+40+(26*3)
  82.     char    SampleText[FONTSAMPLESIZE];
  83.     int     i;
  84.     char    c;
  85.  
  86.     strcpy (SampleText, FaceName);
  87.     i = strlen (SampleText);
  88.     strcpy (&SampleText[i], " (Height=");
  89.     i += strlen (&SampleText[i]);
  90.     itoa (m->tmHeight, &SampleText[i], 10);
  91.     i += strlen (&SampleText[i]);
  92.     strcpy (&SampleText[i], ", Width=");
  93.     i += strlen (&SampleText[i]);
  94.     itoa (m->tmAveCharWidth, &SampleText[i], 10);
  95.     i += strlen (&SampleText[i]);
  96.     strcpy (&SampleText[i], ") sample:");
  97.     i += strlen (&SampleText[i]);
  98.     for (c = 'A'; c <= 'Z'; c++) {
  99.     SampleText[i++] = ' ';
  100.     SampleText[i++] = c;
  101.     SampleText[i++] = tolower(c);
  102.     }
  103.     SampleText[i] = '\0';
  104.     SendDlgItemMessage (hDlg, ID_SAMPLE, WM_SETFONT, hFont, FALSE);
  105.     SetDlgItemText (hDlg, ID_SAMPLE, SampleText);
  106. } /* UpdateSample */
  107.  
  108. /* NewFont: creates a font matching the user's selections */
  109. /* =======                                                */
  110.  
  111. static void pascal near    NewFont (HWND hDlg, BOOL TrustSizeEdit)
  112. /* setting TrustSizeEdit to FALSE indicates that the contents of the
  113.    ID_FONTSIZE edit box should not be used (this is used when this
  114.    function is called for a size list-selection change, at which time
  115.    the edit box has not been updated yet) */
  116. {
  117.     DWORD   d;
  118.     int     i;
  119.     BOOL    FontSizeOK;
  120.     LOGFONT lf;
  121.     HFONT   hOldFont;
  122.  
  123.     hOldFont = hNewFont;
  124.     i = SendDlgItemMessage (hDlg, ID_FONT, LB_GETCURSEL, 0, 0L);
  125.     if (i == LB_ERR) lf.lfFaceName[0] = 0;
  126.     else {
  127.     SendDlgItemMessage (hDlg, ID_FONT, LB_GETTEXT, i,
  128.                         (DWORD)(LPSTR)lf.lfFaceName);
  129.     }
  130.     if (TrustSizeEdit) {
  131.         i = GetDlgItemInt (hDlg, ID_FONTSIZE, &FontSizeOK, FALSE);
  132.     }
  133.     else FontSizeOK = FALSE;
  134.     if (FontSizeOK) {
  135.     lf.lfHeight = i;
  136.     lf.lfWidth = 0;
  137.     }
  138.     else {
  139.     i = SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_GETCURSEL, 0, 0L);
  140.     if (i == CB_ERR) i = 0;
  141.     d = SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_GETITEMDATA, i, 0L);
  142.     lf.lfHeight = HIWORD(d);
  143.     lf.lfWidth = LOWORD(d);
  144.     }
  145.     lf.lfEscapement = 0;
  146.     lf.lfOrientation = 0;
  147.     lf.lfWeight = IsDlgButtonChecked (hDlg, ID_BOLD) ? 700 : 400;
  148.     lf.lfItalic = 0;
  149.     lf.lfUnderline = 0;
  150.     lf.lfStrikeOut = 0;
  151.     lf.lfCharSet = IsDlgButtonChecked (hDlg, ID_ANSI) ?
  152.                    ANSI_CHARSET : OEM_CHARSET;
  153.     lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  154.     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  155.     lf.lfQuality = DEFAULT_QUALITY;
  156.     lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
  157.  
  158.     hNewFont = CreateFontIndirect (&lf);
  159.     GetFontMetrics (hNewFont, &Metrics, FaceName);
  160.     UpdateMaxRowCol (hDlg, hNewFont);
  161.     UpdateSample (hDlg, hNewFont, &Metrics, FaceName);
  162.     if (hOldFont) DeleteObject (hOldFont);
  163. } /* NewFont */
  164.  
  165. /* AddSize: Add a font size into the font size list (used by EnumSizesProc) */
  166. /* =======                                                                  */
  167.  
  168. static void pascal near AddSize (HWND hDlg, short int Height, short int Width)
  169. {
  170.     char    ItemText[17];
  171.     int     i;
  172.  
  173.     itoa (Height, ItemText, 10);
  174.     i = SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_ADDSTRING, 0,
  175.                 (DWORD)(LPSTR)ItemText);
  176.     SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_SETITEMDATA, i,
  177.             MAKELONG(Width,Height));
  178.     
  179. } /* AddSize */
  180.  
  181. /* EnumSizesProc:   font enumeration function used by BuildSizeList */
  182. /* =============                                                    */
  183. int EXPORT far pascal EnumSizesProc (LPLOGFONT lf, LPTEXTMETRIC tm,
  184.                                      short FontType, LPSTR Data)
  185.  
  186. /* Data should point to a handle to the dialog box */
  187. {
  188.     if ((lf->lfWeight > 400) || lf->lfItalic || lf->lfUnderline ||
  189.         lf->lfStrikeOut) return 1;
  190.     if (FontType & 0x04) {  /* SCALABLE_FONTYPE */
  191.         /* make a size list up */
  192.         short int h;
  193.         
  194.         for (h = lf->lfHeight / 3; h <= lf->lfHeight; h += 2) {
  195.             AddSize (*(HWND far *)Data, h, 0);
  196.         }
  197.         return 0;   /* no need to list this one further */
  198.     }
  199.     else {  /* non-scalable font */
  200.         /* list it only if it has a proper aspect ratio */
  201.         HFONT   hFont;
  202.         LOGFONT Font;
  203.         TEXTMETRIC Metrics; 
  204.  
  205.     Font = *lf;
  206.     Font.lfWidth = 0;
  207.     hFont = CreateFontIndirect (&Font);
  208.     GetFontMetrics (hFont, &Metrics, NULL);
  209.     DeleteObject (hFont);
  210.     if (tm->tmAveCharWidth == Metrics.tmAveCharWidth) {
  211.         AddSize (*(HWND far *)Data, lf->lfHeight, lf->lfWidth);
  212.     }
  213.     }
  214.     return 1;
  215. } /* EnumSizesProc */
  216.  
  217. /* BuildSizeList:   initializes the FontSize list box */
  218. /* =============                                      */
  219.  
  220. static void pascal near BuildSizeList (HWND hDlg, TEXTMETRIC *Metrics)
  221.  
  222. /* This function initializes the FontSize list box with the sizes
  223.    available for the face name currently selected in the Font list box.
  224.    The sizes are written in the format: CXxCY. Also, the sizes are
  225.    stored in the 32 bit values retrievable by LB_GETITEMDATA: width in
  226.    the low-order word and height in the high order word */
  227. {
  228.     SendDlgItemMessage (hDlg, ID_FONTSIZE, WM_SETREDRAW, FALSE, 0L);
  229.     SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_RESETCONTENT, 0, 0L);
  230.     {
  231.     HDC     hDC;
  232.     FARPROC ProcInstance;
  233.     char    FaceName[LF_FACESIZE];
  234.  
  235.     SendDlgItemMessage (hDlg, ID_FONT, LB_GETTEXT,
  236.                 SendDlgItemMessage (hDlg, ID_FONT,
  237.                         LB_GETCURSEL, 0, 0L),
  238.                 (DWORD)(LPSTR)FaceName);
  239.         /* FaceName now contains the currently selected face name */
  240.     hDC = GetDC (hDlg);
  241.     ProcInstance = MakeProcInstance ((FARPROC)EnumSizesProc,
  242.                      hEmacsInstance);
  243.     EnumFonts (hDC, FaceName, ProcInstance, (LPSTR)&hDlg);
  244.     FreeProcInstance (ProcInstance);
  245.     ReleaseDC (hDlg, hDC);
  246.     }
  247.     SendDlgItemMessage (hDlg, ID_FONTSIZE, WM_SETREDRAW, TRUE, 0L);
  248.     InvalidateRect (GetDlgItem (hDlg, ID_FONTSIZE), NULL, TRUE);
  249.     {   /*-Select the larger height that is smaller or equal to the
  250.        current Metrics (assumed to be the ones of the previous font)
  251.        */
  252.     int     i;
  253.     int     BestIndex = 0;
  254.     short int h, w, BestHeight = 0, BestWidth = 0;
  255.     DWORD   ItemData;
  256.  
  257.     for (i = 0;; i++) {
  258.         ItemData = SendDlgItemMessage (hDlg, ID_FONTSIZE,
  259.                        CB_GETITEMDATA, i, 0L);
  260.         if (ItemData == CB_ERR) break;  /* end of list hit */
  261.         if ((h = HIWORD(ItemData)) > Metrics->tmHeight) continue;
  262.         if (BestHeight > h) continue;
  263.         w = LOWORD(ItemData);
  264.         if (BestHeight == h) {  /* use the width to optimize */
  265.         if (w > Metrics->tmAveCharWidth) continue;
  266.         if (BestWidth > w) continue;
  267.         }
  268.         BestHeight = h;
  269.         BestWidth = w;
  270.         BestIndex = i;
  271.     }
  272.     SendDlgItemMessage (hDlg, ID_FONTSIZE, CB_SETCURSEL, BestIndex, 0L);
  273.     }
  274.     NewFont (hDlg, TRUE);
  275. } /* BuildSizeList */
  276.  
  277. /* AddFace: Adds a face to the FONT list box if it begets a proper font */
  278. /* =======                                                              */
  279.  
  280. static void pascal near AddFace (HWND hDlg, char *CandidateFace)
  281. {
  282.     BYTE    CharSet;
  283.     int     From, At;   /* indexes for list box searches */
  284.     HFONT   hFixedFont;
  285.     char    FaceName [LF_FACESIZE];
  286.     TEXTMETRIC tm;
  287.     
  288.     CharSet = (IsDlgButtonChecked (hDlg, ID_ANSI) ?
  289.                ANSI_CHARSET : OEM_CHARSET);
  290.     /*-try to identify a fixed-pitch font of set CharSet, with the
  291.        specified face name */
  292.     hFixedFont = CreateFont (0, 0, 0, 0, 0, FALSE, FALSE, FALSE,
  293.                  CharSet, OUT_DEFAULT_PRECIS,
  294.                  CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
  295.                  FF_DONTCARE+FIXED_PITCH,
  296.                  CandidateFace);
  297.     GetFontMetrics (hFixedFont, &tm, FaceName);
  298.     DeleteObject (hFixedFont);
  299.     if ((tm.tmPitchAndFamily & 0x01) || /* =1 if variable pitch */
  300.     (tm.tmCharSet != CharSet) ||
  301.     (strcmp (FaceName, CandidateFace) != 0)) {
  302.     /* flunked the exam! */
  303.     return;     /* skip that face */
  304.     }
  305.     /* the candidate face has at least one fixed-pitch font with the
  306.        right charset */
  307.     /*- scan the list box to make sure this face is not a duplicate */
  308.     At = -1;    /* start at beginning of list box */
  309.     do {
  310.     From = At;
  311.     At = SendDlgItemMessage (hDlg, ID_FONT, LB_FINDSTRING, From,
  312.                                  (DWORD)CandidateFace);
  313.         if (At == LB_ERR) break;    /* no match, implies not duplicate */
  314.     if (SendDlgItemMessage (hDlg, ID_FONT, LB_GETTEXTLEN, At, 0L) ==
  315.             strlen(CandidateFace)) {
  316.             /* the lengths match, that means the strings match so it is
  317.            indeed a duplicate */
  318.         return;
  319.     }
  320.     } while (At > From);    /* exit if search has gone through the
  321.                    bottom of the list box */
  322.  
  323.     /*-it is a brand new face, let's add it to the list */
  324.     SendDlgItemMessage (hDlg, ID_FONT, LB_ADDSTRING, 0, (DWORD)CandidateFace);
  325.     return;
  326. } /* AddFace */
  327.  
  328. /* EnumFacesProc:   face enumeration function used by BuildFaceList */
  329. /* =============                                                    */
  330. int EXPORT far pascal EnumFacesProc (LPLOGFONT lf, LPTEXTMETRIC tm,
  331.                                      short FontType, LPSTR Data)
  332.  
  333. /* Data should point to a handle to the dialog box */
  334. /* lists only fixed pitch fonts that match the selected charset */
  335. {
  336.     AddFace (*(HWND far *)Data, lf->lfFaceName);
  337.     return 1;
  338. } /* EnumFacesProc */
  339.  
  340. /* BuildFaceList:   initialize the FONT list box */
  341. /* =============                                 */
  342.  
  343. static void pascal near BuildFaceList (HWND hDlg, char *FaceName)
  344.  
  345. /* This function initializes the Font list box with fixed fonts matching
  346.    the current charset selection and then selects an item */
  347. {
  348.     SendDlgItemMessage (hDlg, ID_FONTSIZE, WM_SETREDRAW, FALSE, 0L);
  349.     SendDlgItemMessage (hDlg, ID_FONT, LB_RESETCONTENT, 0, 0L);
  350.     {
  351.     HDC     hDC;
  352.     FARPROC ProcInstance;
  353.  
  354.     hDC = GetDC (hDlg);
  355.     ProcInstance = MakeProcInstance ((FARPROC)EnumFacesProc,
  356.                      hEmacsInstance);
  357.     EnumFonts (hDC, NULL, ProcInstance, (LPSTR)&hDlg);
  358.     FreeProcInstance (ProcInstance);
  359.     ReleaseDC (hDlg, hDC);
  360.     }
  361.     SendDlgItemMessage (hDlg, ID_FONT, WM_SETREDRAW, TRUE, 0L);
  362.     InvalidateRect (GetDlgItem (hDlg, ID_FONT), NULL, TRUE);
  363.     /*-select the same facename as before or default to the first item */
  364.     if (SendDlgItemMessage (hDlg, ID_FONT, LB_SELECTSTRING, -1, FaceName)
  365.         == LB_ERR) {
  366.     SendDlgItemMessage (hDlg, ID_FONT, LB_SETCURSEL, 0, 0L);
  367.     }
  368.     BuildSizeList (hDlg, &Metrics);
  369. } /* BuildFaceList */
  370.  
  371. /* FontDlgProc: Emacs Font dialog box function */
  372. /* ===========                                 */
  373. int EXPORT far pascal  FontDlgProc (HWND hDlg, WORD wMsg, WORD wParam,
  374.                     DWORD lParam)
  375. {
  376.     switch (wMsg) {
  377.         
  378.     case WM_INITDIALOG:
  379.         hNewFont = NULL;
  380.     {   /*-setup the dialog box's caption */
  381.         char    s[40];
  382.  
  383.         strcpy (s, ProgName);
  384.         strcat (s, " - Font selection");
  385.         SetWindowText (hDlg, s);
  386.     }
  387.     /*-set the Bold button */
  388.     GetFontMetrics (hEmacsFont, &Metrics, FaceName);
  389.     CheckDlgButton (hDlg, ID_BOLD, (Metrics.tmWeight > 550));
  390.     {   /*-simulate a mouse click on the appropriate charset
  391.            radiobutton. This will initialize all the other controls
  392.            */
  393.         WORD    id;
  394.         
  395.         id = (Metrics.tmCharSet == ANSI_CHARSET ? ID_ANSI : ID_OEM);
  396.         SendMessage (hDlg, WM_COMMAND, id,
  397.              MAKELONG(GetDlgItem (hDlg, id), BN_CLICKED));
  398.     }
  399.         return TRUE;
  400.  
  401.     case WM_COMMAND:
  402.     switch (wParam) {
  403.     case 1:     /* OK button */
  404.         if (HIWORD(lParam) == BN_CLICKED) {
  405. AcceptFont:
  406.         if (hEmacsFont) DeleteObject (hEmacsFont);
  407.         hEmacsFont = hNewFont;
  408.         EndDialog (hDlg, TRUE);
  409.         /* no need to unhook the SAMPLE's font, it is not
  410.            destroyed since it will be used by emacs */
  411.         }
  412.         else return FALSE;
  413.         break;
  414.     case 2:     /* Cancel button */
  415.         if (HIWORD(lParam) == BN_CLICKED) goto CancelFont;
  416.         else return FALSE;
  417.     case ID_SAVEFONT:
  418.         if (HIWORD(lParam) == BN_CLICKED) {
  419.         /*-save the facename, bold status and size into WIN.INI,
  420.            then perform as the OK button */
  421.         char    NumText[17];
  422.             
  423.         GetFontMetrics (hNewFont, &Metrics, FaceName);
  424.         WriteProfileString (ProgName, "FontName", FaceName);
  425.         WriteProfileString (ProgName, "CharSet",
  426.                             itoa (Metrics.tmCharSet, NumText, 10));
  427.         WriteProfileString (ProgName, "FontHeight",
  428.                             itoa (Metrics.tmHeight, NumText, 10));
  429.         WriteProfileString (ProgName, "FontWidth",
  430.                             itoa (Metrics.tmAveCharWidth,
  431.                                           NumText, 10));
  432.         WriteProfileString (ProgName, "FontWeight",
  433.                             itoa (Metrics.tmWeight, NumText, 10));
  434.             }
  435.         else return FALSE;
  436.         goto AcceptFont;
  437.     case ID_ANSI:
  438.     case ID_OEM:
  439.         if (HIWORD(lParam) == BN_CLICKED) {
  440.             CheckRadioButton (hDlg, ID_1ST_CHARSET, ID_LAST_CHARSET,
  441.                                   wParam);
  442.         BuildFaceList (hDlg, FaceName);
  443.         }
  444.         else return FALSE;
  445.         break;
  446.     case ID_BOLD:
  447.         if (HIWORD(lParam) == BN_CLICKED) NewFont (hDlg, TRUE);
  448.         else return FALSE;
  449.         break;
  450.     case ID_FONT:
  451.         switch (HIWORD(lParam)) {
  452.         case LBN_SELCHANGE:
  453.         BuildSizeList (hDlg, &Metrics);
  454.         break;
  455.         case LBN_DBLCLK:    /* treated as OK */
  456.         goto AcceptFont;
  457.         default:
  458.         return FALSE;
  459.         }
  460.         break;
  461.     case ID_FONTSIZE:
  462.         switch (HIWORD(lParam)) {
  463.         case CBN_SELCHANGE:
  464.         NewFont (hDlg, FALSE);
  465.         break;
  466.         case CBN_EDITCHANGE:
  467.             {
  468.             BOOL    FontSizeOK;
  469.  
  470.             GetDlgItemInt (hDlg, ID_FONTSIZE, &FontSizeOK, FALSE);
  471.             if (FontSizeOK) NewFont (hDlg, TRUE);
  472.             else MessageBeep (0);
  473.         }
  474.         break;
  475.         case CBN_DBLCLK:    /* treated as OK */
  476.         goto AcceptFont;
  477.         default:
  478.         return FALSE;
  479.         }
  480.         break;
  481.     default:
  482.         return FALSE;
  483.         }
  484.     break;
  485.     case WM_SYSCOMMAND:
  486.     if ((wParam & 0xFFF0) == SC_CLOSE) {
  487. CancelFont:
  488.         EndDialog (hDlg, FALSE);
  489.         if (hNewFont) {
  490.         SendDlgItemMessage (hDlg, ID_SAMPLE, WM_SETFONT, 0, FALSE);
  491.             /* reset to SYSTEM_FONT before deleting the font */
  492.         DeleteObject (hNewFont);
  493.         }
  494.         return TRUE;
  495.     }
  496.     return FALSE;
  497.     default:
  498.     return FALSE;
  499.     }
  500.     return FALSE;
  501. } /* FontDlgProc */
  502.  
  503. /* ChangeFont:  effects the font change on the screen & message line */
  504. /* ==========                                                         */
  505. static void pascal near ChangeFont (void)
  506.  
  507. {
  508.     SCREEN  *sp, *fsp;
  509.     RECT    Rect;
  510.  
  511.     /*-loop through all the screens, resizing the vision that emacs has
  512.        of them, processing the current ("first") screen last */
  513.     InternalRequest = TRUE;
  514.     fsp = first_screen;
  515.     do {
  516.     sp = first_screen;
  517.     while (sp->s_next_screen != (SCREEN *)NULL) sp = sp->s_next_screen;
  518.         select_screen (sp, FALSE);
  519.         GetClientRect (sp->s_drvhandle, &Rect);
  520.         newwidth (TRUE, DisplayableColumns (sp->s_drvhandle,
  521.                                             Rect.right, &EmacsCM));
  522.         newsize (TRUE, DisplayableRows (sp->s_drvhandle,
  523.                                         Rect.bottom, &EmacsCM));
  524.     } while (sp != fsp);
  525.     InternalRequest = FALSE;
  526.  
  527.     /*-update the frame's client area and the MDIClient's size */
  528.     InvalidateRect (hFrameWnd, NULL, TRUE);
  529.     GetClientRect (hFrameWnd, &Rect);
  530.     MoveWindow (hMDIClientWnd, 0, 0,
  531.                 Rect.right, Rect.bottom - EmacsCM.MLHeight,
  532.                 TRUE);
  533. } /* ChangeFont */
  534.  
  535. /* PickEmacsFont:   calls-up the FONTS dialog box */
  536. /* =============                                  */
  537.  
  538. BOOL far pascal PickEmacsFont (void)
  539.  
  540. /* returns TRUE is a new font has been picked */
  541. {
  542.     BOOL    FontChanged;
  543.     FARPROC ProcInstance;
  544.  
  545.     ProcInstance = MakeProcInstance ((FARPROC)FontDlgProc,
  546.                      hEmacsInstance);
  547.     FontChanged = DialogBox (hEmacsInstance, "FONTS",
  548.                  hFrameWnd, ProcInstance);
  549.     FreeProcInstance (ProcInstance);
  550.  
  551.     if (FontChanged) {
  552.     BuildCellMetrics (&EmacsCM, hEmacsFont);
  553.         ChangeFont ();
  554.     return TRUE;
  555.     }
  556.     else return FALSE;
  557. } /* PickEmacsFont */
  558.  
  559. /* FontInit:    initialize a font description from WIN.INI */
  560. /* ========                                                */
  561.  
  562. void far pascal FontInit (void)
  563. {
  564.     LOGFONT lf;
  565.     char    text[20];
  566.  
  567.     if (GetProfileString (ProgName, "CharSet", "", text, 20)) {
  568.         if (isdigit(text[0])) { /* pure numeric value */
  569.             lf.lfCharSet = atoi (text);
  570.         }
  571.         else {  /* menmonic value */
  572.         if (strncmp (text, "OEM", 3) == 0) {
  573.         lf.lfCharSet = OEM_CHARSET;
  574.         }
  575.         else lf.lfCharSet = ANSI_CHARSET;
  576.     }
  577.     lf.lfHeight = GetProfileInt (ProgName, "FontHeight", 0);
  578.     lf.lfWidth = GetProfileInt (ProgName, "FontWidth", 0);
  579.     lf.lfEscapement = 0;
  580.     lf.lfOrientation = 0;
  581.     lf.lfWeight = GetProfileInt (ProgName, "FontWeight", 400);
  582.     lf.lfItalic = 0;
  583.     lf.lfUnderline = 0;
  584.     lf.lfStrikeOut = 0;
  585.     lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
  586.     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  587.     lf.lfQuality = DEFAULT_QUALITY;
  588.     lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
  589.         GetProfileString (ProgName, "FontName", "",
  590.                           lf.lfFaceName, LF_FACESIZE);
  591.  
  592.         hEmacsFont = CreateFontIndirect (&lf);
  593.     }
  594.     else {  /* no CharSet entry, default to SYSTEM_FIXED_FONT */
  595.     hEmacsFont = 0;
  596.     }
  597.     BuildCellMetrics (&EmacsCM, hEmacsFont);
  598. } /* FontInit */
  599.